# !/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time : 2021/8/31 15:32
# @Author : Yu LiXinQian
# @Email : yulixinqian805@gmail.com
# @File : PCA.py
# @Project : My_MLF
from scipy.io import loadmat
import numpy as np
import matplotlib.pyplot as plt


class PCA:
    def __init__(self, X, k=None):
        self.X = X
        self.k = k

    def NormalizeFeatures(self):
        # normalize the features
        X = (self.X - self.X.mean(axis=1,keepdims=True)) / self.X.std(axis=1, keepdims=True)

        # compute the covariance matrix
        cov = np.dot(X, X.T) / X.shape[1]

        # perform SVD
        U, S, V = np.linalg.svd(cov)

        return U, S, V

    def ProjectData(self, V):
        if self.k is None:
            k=self.X.shape[0]
        else:
            k=self.k

        Z = np.dot(V[:, 0:k].T, self.X)

        return Z

    def RebuildData(self, Z, V):
        if self.k is None:
            k=self.X.shape[0]
        else:
            k=self.k

        X = np.dot(V[:, 0:k], Z)

        return X






if __name__ == '__main__':
    data = loadmat('Data/ex7data1.mat')  # dictionary
    X = data['X']
    X = X.T
    pca = PCA(X,1)
    u, s, v = pca.NormalizeFeatures()
    Z = pca.ProjectData(v)
    XX = pca.RebuildData(Z, v)

    X = (X - X.mean(axis=1, keepdims=True)) / X.std(axis=1, keepdims=True)

    plt.scatter(X[0],X[1])
    plt.scatter(XX[0], XX[1], color='red')
    # plt.xlim(0, 8)  # 设置x轴边界，left，right
    # plt.ylim(0, 8)
    plt.show()